package com.tramy.cn.push.sender;

import com.tramy.cn.push.common.Data;
import com.tramy.cn.push.common.ErrorListener;
import com.tramy.cn.push.common.PushRes;
import com.tramy.cn.push.common.VIVOInfo;
import com.vivo.push.sdk.notofication.Message;
import com.vivo.push.sdk.notofication.Result;
import com.vivo.push.sdk.server.Sender;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class VIVOSender implements PushSender {

    public static final Log logger = LogFactory.getLog(VIVOSender.class);

    private static final long PERIOD = 60 * 60 * 1000;

    private Sender sender;

    private final ErrorListener errorListener;

    private final ExecutorService executorService;

    public VIVOSender(VIVOInfo info) {
        try {
            sender = new Sender(info.getAppSecret());

            refreshAuthToken(info.getAppId(), info.getAppKey());
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    refreshAuthToken(info.getAppId(), info.getAppKey());
                }
            }, PERIOD, PERIOD);
        }catch (Exception e) {
            logger.error("【CNPUSH SDK - VIVO】" + e.getMessage());
        }

        errorListener = info.getErrorListener();
        executorService = Executors.newFixedThreadPool(
                info.getPoolSize() == null ? 10 : info.getPoolSize());
    }

    private void refreshAuthToken(Integer appId,
                                  String appKey) {
        try {
            Result result = sender.getToken(appId, appKey);
            if (result.getResult() == PushRes.SUCCESS) {
                sender.setAuthToken(result.getAuthToken());

                logger.info("【CNPUSH SDK - VIVO】authToken已更新为" + result.getAuthToken());
            }else {
                logger.error("【CNPUSH SDK - VIVO】authToken更新失败");
            }
        }catch (Exception e) {
            logger.error("【CNPUSH SDK - VIVO】authToken更新失败");
        }
    }

    @Override
    public PushRes sendData(List<Data> dataList) {
        if (dataList == null || dataList.isEmpty()) {
            logger.info("【CNPUSH SDK - VIVO】目标平台没有要进行的推送");
            return PushRes.ok();
        }

        List<Message> messages = getMessages(dataList);

        for (Message message : messages) {
            executorService.execute(() -> {
                try {
                    Result result = sender.sendSingle(message);
                    if (result.getResult() != PushRes.SUCCESS) {
                        String errorInfo = message.getRegId() +
                                "," +
                                result.getResult() +
                                "," +
                                result.getDesc();

                        if (errorListener != null) {
                            errorListener.onReceiveInfo(errorInfo);
                        }
                    }
                }catch (Exception e) {
                    String errorInfo = message.getRegId() +
                            "," +
                            e.toString();

                    if (errorListener != null) {
                        errorListener.onReceiveInfo(errorInfo);
                    }
                }
            });
        }

        return PushRes.ok();
    }

    private List<Message> getMessages(List<Data> dataList) {
        List<Message> messages = new LinkedList<>();
        for (Data data : dataList) {
            Message message = new Message.Builder()
                    .regId(data.getToken())
                    .title(data.getTitle())
                    .content(data.getContent())
                    .timeToLive(1000)
                    .notifyType(data.getLevel() + 1)
                    .skipType(1)
                    .requestId(UUID.randomUUID().toString())
                    .classification(data.getLevel())
                    .build();
            messages.add(message);
        }

        return messages;
    }

}
